<template>
	<!-- 播放器 -->
  <div class="player" v-show="playlist.length>0">
	<!-- 播放器 -->
		<transition name="normal" @enter="enter" @after-enter="afterEnter" @leave="leave" @after-leave="afterLeave">
			<!-- img -->
			<div class="normal-player" v-show="fullScreen">
				<div class="background"><img width="100%" height="100%" :src="currentSong.pic"></div>
					<!-- btn -->
					<div class="top">
						<div class="back" @click="back">
							<div class="icon-back"></div>
						</div>
						<h1 class="title" v-html="currentSong.name"></h1>
						<h2 class="subtitle" v-html="currentSong.singer"></h2>
					</div>
					<!-- 唱片机 3个滑动事件-->
					<div class="middle"
						@touchstart.prevent="middleTouchStart"
						@touchmove.prevent="middleTouchMove"
						@touchend="middleTouchEnd"
					>
						<div class="middle-l" ref="middleL">
							<div class="cd-wrapper" ref="cdWrapper">
								<!-- 不停运动的小圆盘 -->
								<div class="cd" :class="cdCls"><img :src="currentSong.pic" alt="" class="image"></div>
							</div>
							<!-- cd页面歌词 -->
							<div class="playing-lyric-wrapper">
								<div class="playing-lyric">{{playingLyric}}</div>
							</div>
						</div>
						<!-- 歌词的界面 -->
						<scroll class="middle-r" ref="lyricList" :dataA="currentLyric && currentLyric.lines">
							<div class="lyric-wrapper">
								<div v-if="currentLyric">
									<p ref="lyricLine"
										 class="text"
										 :class="{'current': currentLineNum ===index}" :key="index"
										 v-for="(line,index) in currentLyric.lines">{{line.txt}}</p>
								</div>
							</div>
						</scroll>
						
					</div>
					<!-- 底部操作区 -->
					<div class="bottom">
						<div class="dot-wrapper">
							<span class="dot" :class="{'active':currentShow==='cd'}"></span>
							<span class="dot" :class="{'active':currentShow==='lyric'}"></span>
						</div>
						<div class="progress-wrapper">
							<!-- 歌曲播放当前时间 -->
							<span class="time time-l">{{format(currentTime)}}</span>
							<div class="progress-bar-wrapper">
								<!-- 音乐播发时间线条组件 -->
							  <progress-bar :percent="percent" 
							    @percentChange="onProgressBarChange">
								</progress-bar>
							</div>
							<!-- 歌曲播放总时间 -->
							<span class="time time-r">{{format(currentSong.time)}}</span>
						</div>
						<div class="operators">
							<!-- 播放模式 -->
							<div class="icon i-left" @click="changeMode"><i :class="iconMode"></i></div>
							<div class="icon i-left" :class="disableCls"><i class="icon-prev" @click="prev"></i></div>
							<!-- 播放或暂停 -->
							<div class="icon i-center" :class="disableCls">
								<i @click="togglePlaying" :class="playIcon"></i>
							</div>
							<div class="icon i-right" :class="disableCls">
								<i class="icon-next" @click="next"></i>
							</div>
							<!-- 收藏 -->
							<div class="icon i-right">
								<i :class="getFavoriteIcon(currentSong)"  @click="toggleFavorite(currentSong)" class="icon"></i>
							</div>
						</div>
					</div>	
			</div>
			
		</transition>
		<!-- 底部迷里播放器 -->
		<transition name="mini" >
				<div class="mini-player" v-show="!fullScreen" @click.stop="open">
					<!-- 不停运动的小圆盘 -->
					<div class="icon"><img :class="cdCls" width="40" height="40"  :src="currentSong.pic" alt=""></div>
					<div class="text">
						<h2 class="name" v-html="currentSong.name"></h2>
						<p class="desc" v-html="currentSong.singer"></p>
					</div>
					<!-- 播放或暂停 -->
					<div class="control"><!-- 迷里小园圈播放器组件 -->
						<progress-circle :radius="radius" :percent="percent">
							<i @click.stop="togglePlaying" class="icon-mini" :class="miniIcon"></i>
						</progress-circle>
					</div>
					<!-- 点击图标显示playlist列表 -->
					<div class="control" @click.stop="showPlaylist"><i class="icon-playlist"></i></div>
				</div>
			
		</transition>
		<playlist ref="playlist"></playlist>
		<!--canplay 歌曲准备就绪 timeupdate 歌曲播放派发时间 error 发生错误 -->
		<audio id="music_mp3_0" ref="audio" :src="currentSong.url" @play="ready"
		@error="error" @timeupdate="updateTime" @ended="end">
		</audio> 
  </div>
</template>

<script>
import {mapGetters, mapMutations, mapActions} from 'vuex'
import animations from 'create-keyframe-animation'
import {prefixStyle} from 'common/js/dom'
import {playMode} from 'common/js/config'
import Scroll from 'base/scroll/scroll'
import Lyric from 'lyric-parser' //生成lines条数
import {VoCalist} from 'api/singer'; //首页请求方式
import ProgressBar from 'base/progress-bar/progress-bar'
import ProgressCircle from 'base/progress-circle/progress-circle'
import Playlist from 'components/playlist/playlist'
import {playerMixin,playpop} from 'common/js/mixin'

const transform = prefixStyle('transform')
const transitionDuration = prefixStyle('transitionDuration')
export default {
  name: 'palyer',
	mixins: [playerMixin,playpop],
	created() {this.touch = {}},
	data(){
		return{
			songReady:false,//歌曲准备就绪
			currentTime: 0,
			radius:32,
			currentLyric: null,//歌词
			currentLineNum: 0,//歌词高亮行数
			currentShow: 'cd',//歌词页面滑动参数
			playingLyric: '',
		}
	},
	methods: {
		back() {this.setFullScreen(false)},
		open(){this.setFullScreen(true)},
		enter(el, done) {
			const {x, y, scale} = this._getPosAndScale()
			let animation = {
				0: {
					transform: `translate3d(${x}px,${y}px,0) scale(${scale})`
				},
				60: {
					transform: `translate3d(0,0,0) scale(1.1)`
				},
				100: {
					transform: `translate3d(0,0,0) scale(1)`
				}
			}
			animations.registerAnimation({//动画配置 
				name: 'move',
				animation,
				presets: {
					duration: 400,
					easing: 'linear'
				}
			})
			 //动画引用
			animations.runAnimation(this.$refs.cdWrapper, 'move', done)
		},
		afterEnter() {
			animations.unregisterAnimation('move')
			this.$refs.cdWrapper.style.animation = ''
		},
		leave(el, done) {
			this.$refs.cdWrapper.style.transition = 'all 0.4s'
			const {x, y, scale} = this._getPosAndScale()
			this.$refs.cdWrapper.style[transform] = `translate3d(${x}px,${y}px,0) scale(${scale})`
			this.$refs.cdWrapper.addEventListener('transitionend', done)
		},
		afterLeave() {
			this.$refs.cdWrapper.style.transition = ''
			this.$refs.cdWrapper.style[transform] = ''
		},
		_getPosAndScale() {//定义动画的简单函数
			const targetWidth = 40 //小圆圈的宽度
			const paddingLeft = 40
			const paddingBottom = 30
			const paddingTop = 80
			const width = window.innerWidth * 0.8 //唱片的宽度
			const scale = targetWidth / width
			const x = -(window.innerWidth / 2 - paddingLeft)
			const y = window.innerHeight - paddingTop - width / 2 - paddingBottom
			return {
				x,
				y,
				scale
			}
		},
		togglePlaying(){//底部迷你播放或暂停
			if(!this.songReady){return}
			this.setPlayingState(!this.playing)//暂停歌词也要暂停
			if(this.currentLyric){this.currentLyric.togglePlay()
			}
		},
		next(){//下一首歌曲
			if(!this.songReady){return}
			if(this.playlist.length === 1) {//如果只有一条信息
          this.loop()
          return
			}else{
				let index=this.currentIndex+1;
				if(index==this.playlist.length){index=0}
				this.NexTsell({list:this.playlist,index})	// this.NexTsell({list:this.sequenceList,index})
				if(!this.playing){this.togglePlaying()
				}
			} 
			this.songReady=false;
		},
		prev(){//上一首歌曲
			if(!this.songReady){return}
			 if (this.playlist.length === 1) {
          this.loop()
          return
        } else {
					let index=this.currentIndex-1;
					if(index==-1){index=this.playlist.length-1}
					this.NexTsell({list:this.playlist,index})
					if (!this.playing) {this.togglePlaying()}
				}
			if(!this.playing){this.togglePlaying()}
			this.songReady=false;
		},
		ready(){//歌曲准备就绪 写入历史数据
			this.songReady=true
			this.savePlayHistory(this.currentSong)
		},
		error(){//歌曲错误信息
			this.songReady=true
			console.log("歌曲错误信息oo")
		},
		end() { //切换到下一首
			(this.mode === playMode.loop)?this.loop():this.next()
		},
		updateTime(e) { //歌曲播放派发时间
			this.currentTime = e.target.currentTime
		},
		format(interval) { //秒的时间戳转化
			interval = interval | 0
			const minute = interval / 60 | 0
			const second = this._pad(interval % 60)
			return `${minute}:${second}`
		},
		_pad(num, n = 2) {//秒的扑0 00：59
			let len = num.toString().length
			while (len < n) {
				num = '0' + num
				len++
			}
			return num
		},
		onProgressBarChange(percent) {// duration总时长 实时更新小球时间 progress-bar
			const currentTime = this.currentSong.time * percent  //8%*500s公式
			this.$refs.audio.currentTime = currentTime
			if (!this.playing) {this.togglePlaying()}//拖动小球 歌词也跟着滚动
			if (this.currentLyric) {this.currentLyric.seek(currentTime * 1000)}
		},
		loop() {//循环播发的功能
			this.$refs.audio.currentTime = 0
			this.$refs.audio.play()
			// this.setPlayingState(true)
			if (this.currentLyric) {this.currentLyric.seek(0)}
		},
		//获取歌词
		currentlrc(){//快速切换歌词自己走动
				let that=this
				this.$axios.get(this.currentSong.lrc).then((lyric)=>{
						this.currentLyric = new Lyric(lyric.data,this.handleLyric)
						if (this.playing) {this.currentLyric.play()}
				}).catch((err)=>{
					this.currentLyric=null
					this.playingLyric=""
					this.currentLineNum=0
				})
		},
		handleLyric({lineNum, txt}) {//歌词的回调函数
			if (!this.playing){
					this.currentLyric.stop()
					// console.log("暂停了歌词还播放3")
					return
			}
			this.currentLineNum = lineNum
			if (lineNum > 5) {
				let lineEl = this.$refs.lyricLine[lineNum - 5]
				this.$refs.lyricList.scrollToElement(lineEl, 1000)
			} else {
				this.$refs.lyricList.scrollTo(0, 0, 1000)
			}
			this.playingLyric = txt
		},
		middleTouchStart(e) { //滑动跳转页面
			this.touch.initiated = true
			// 用来判断是否是一次移动
			this.touch.moved = false
			const touch = e.touches[0]
			this.touch.startX = touch.pageX
			this.touch.startY = touch.pageY
		},
		middleTouchMove(e) {
			if (!this.touch.initiated) {return}
			const touch = e.touches[0]
			const deltaX = touch.pageX - this.touch.startX
			const deltaY = touch.pageY - this.touch.startY
			if (Math.abs(deltaY) > Math.abs(deltaX)) {return}//如果y纵轴的距离大于x横轴的距离//则取消滑动
			if (!this.touch.moved) {this.touch.moved = true}
			const left = this.currentShow === 'cd' ? 0 : -window.innerWidth
			const offsetWidth = Math.min(0, Math.max(-window.innerWidth, left + deltaX))
			this.touch.percent = Math.abs(offsetWidth / window.innerWidth) //歌词界面滑动百分比
			this.$refs.lyricList.$el.style[transform] = `translate3d(${offsetWidth}px,0,0)`
			this.$refs.lyricList.$el.style[transitionDuration] = 0
			this.$refs.middleL.style.opacity = 1 - this.touch.percent
			this.$refs.middleL.style[transitionDuration] = 0
		},
		middleTouchEnd() {
        if (!this.touch.moved) {return}
        let offsetWidth
        let opacity//右向左滑
        if (this.currentShow === 'cd') {
          if (this.touch.percent > 0.1) {
            offsetWidth = -window.innerWidth
            opacity = 0
            this.currentShow = 'lyric'
          } else {
            offsetWidth = 0
            opacity = 1
          }
        } else {//左向右滑
          if (this.touch.percent < 0.9) {
            offsetWidth = 0
            this.currentShow = 'cd'
            opacity = 1
          } else {
            offsetWidth = -window.innerWidth
            opacity = 0
          }
        }
        const time = 300
        this.$refs.lyricList.$el.style[transform] = `translate3d(${offsetWidth}px,0,0)`
        this.$refs.lyricList.$el.style[transitionDuration] = `${time}ms`
        this.$refs.middleL.style.opacity = opacity
        this.$refs.middleL.style[transitionDuration] = `${time}ms`
        this.touch.initiated = false
      },
			Sgequs(url){ //解决排行点击歌曲无响应
				 let datas=[]
				this.$axios.get(url).then((res)=>{
					if(res.status==200){datas =res.data.data }
				}).catch((err)=>{console.log(err)})
				setTimeout(()=>{
					if(datas){this.CURRENTSONGFALSE(datas)}
				},1000)
			},
      showPlaylist() {//点击显示播放列表
        this.$refs.playlist.show()
      },
		...mapMutations({
			setFullScreen: 'SET_FULL_SCREEN',
			setPlayingState:'SET_PLAYING_STATE',
			setCurrentIndex:'SET_CURRENT_INDEX',
			CURRENTSONG:'CURRENTSONG',
			setPlayMode:'SET_PLAY_MODE',
			setPlaylist:'SET_PLAYLIST' ,
			CURRENTSONGFALSE:'CURRENTSONGFALSE'
		}),
		...mapActions([
			'NexTsell',
			'savePlayHistory'
			])
	},
	computed:{
		cdCls() {//不停运动的小圆盘
			return this.playing ? 'play' : 'play pause'
		},
		playIcon(){ // pla 播放或暂停的图标
			return this.playing?'icon-pause':'icon-play'
		},
		miniIcon(){//min 播放或暂停的图标
			return this.playing ? 'icon-pause-mini' : 'icon-play-mini'
		},
		iconMode(){//播放模式class
			if(this.mode==playMode.sequence){//0
				return "icon-sequence"
			}else if(this.mode==playMode.loop){//1
				return "icon-loop"
			}else{
				return "icon-random"
			}
		},
		disableCls() { //播放禁止
			return this.songReady ? '' : 'disable'
		},
		percent() {//动态计算小球的运动百分比
			return this.currentTime / this.currentSong.time
		},
		...mapGetters([
			'fullScreen',
			'playing',
			'currentIndex',
		])
	},
	watch:{
		currentSong(newSong, oldSong){
			if (!newSong.id) {return}
			if (newSong.id === oldSong.id) {return}
			
			if(!newSong.lrc||!newSong.url){//解决排行榜歌曲没有效果
				 let url=VoCalist(newSong.mid,3)
				this.Sgequs(url)
			}

			//如果已经存在歌词 就取消
			if(this.currentLyric){
					this.currentLyric.stop()
					this.currentTime = 0//time
					this.playingLyric = ''//歌词
					this.currentLineNum = 0 //行数
				}
			//快速切换歌曲 歌词不停跳动bug 
			clearTimeout(this.timer)
			this.timer=setTimeout(()=>{ //解决微信==>切换后台音乐不播放
					this.$refs.audio.play()
					this.currentlrc()
					// console.log("歌词歌曲快速加载")
			},1000)
		},
		playing(newPlaying){//底部播放器开关按钮 
			const audio=this.$refs.audio
			this.$nextTick(()=>{
				if(this.songReady){
					newPlaying?audio.play():audio.pause()
				}
			})
		}
	},
	components: {
      ProgressBar,
      ProgressCircle,
      Scroll,
      Playlist
    }
	
}
</script>

<style lang="scss" scoped >
	.player{
		.normal-player{
			@include qunp();
			z-index: 150;
			.background{
				position: absolute;
				left: 0;
				top: 0;
				width: 100%;
				height: 100%;
				z-index: -1;
				opacity: 0.6;
				filter: blur(20px);
			}
			.top{
				position: relative;
				margin-bottom:25px;
				.back{
					position: absolute;
					top: 0;
					left: 6px;
					z-index: 50;
					.icon-back{
						display: block;
						padding: 9px;
						font-size: $font-size-large-x;
            color: $color-theme;
            transform: rotate(-90deg);
					}
				}
				.title{
					width: 70%;
					margin: 0 auto;
					line-height: 40px;
					text-align: center;
					@include no-wrap();
					font-size: $font-size-large;
					color: $color-text;
				}
				.subtitle{
					line-height: 20px;
					text-align: center;
					font-size: $font-size-medium;
					color: $color-text;
				}
			}
			.middle{
				position: fixed;
				width: 100%;
				top: 80px;
				bottom: 170px;
				white-space: nowrap;
				font-size: 0;
				.middle-l{
					display: inline-block;
					vertical-align: top;
					position: relative;
					width: 100%;
					height: 0;
					padding-top: 80%;
					.cd-wrapper{
						position: absolute;
						left: 10%;
						top: 0;
						width: 80%;
						height: 100%;
						.cd{
							width: 100%;
							height: 100%;
							box-sizing: border-box;
							border: 10px solid rgba(255,255,255,.1);
							border-radius:50%;
							&.play{animation: rotate 20s linear infinite;}
              &.pause{animation-play-state: paused;}
              .image{
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                border-radius: 50%;
							}	
						}
					}
					.playing-lyric-wrapper{
						width: 80%;
						margin: 30px auto 0 auto;
						overflow: hidden;
						text-align: center;
						.playing-lyric{
							height: 20px;
							line-height: 20px;
							font-size: $font-size-medium;
              color: $color-text-l;
						}
					}
				}
				.middle-r{
					display: inline-block;
					vertical-align: top;
					width: 100%;
					height: 100%;
					overflow: hidden;
					.lyric-wrapper{
						width: 80%;
						margin: 0 auto;
						overflow: hidden;
						text-align: center;
						.text{
							line-height: 32px;
							color: $color-text-l;
              font-size: $font-size-medium;
              &.current{color: $color-text;}
						}
					}
				}
			}
			.bottom{
				position: absolute;
        bottom: 50px;
        width: 100%;
				.dot-wrapper{
          text-align: center;
          font-size: 0;
					.dot{
            display: inline-block;
            vertical-align: middle;
            margin: 0 4px;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: $color-text-l;
            &.active{
              width: 20px;
              border-radius: 5px;
              background: $color-text-ll;
						}
					}
				}
				.progress-wrapper{
					display: flex;
          align-items: center;
          width: 80%;
          margin: 0px auto;
          padding: 10px 0;
          .time{
            color: $color-text;
            font-size: $font-size-small;
            flex: 0 0 30px;
            line-height: 30px;
            width: 30px;
            &.time-l{text-align: left;}
            &.time-r{text-align: right;}	
					}
					.progress-bar-wrapper{flex: 1;}
				}
				.operators{
					display: flex;
          align-items: center;
          .icon{
            flex: 1;
            color: $color-theme;
            &.disable{color: $color-theme-d;}
            i{font-size: 30px;}
					}
          .i-left{text-align: right;}
          .i-center{
            padding: 0 20px;
            text-align: center;
            i{font-size: 40px;}
					}
          .i-right{text-align: left;}
          .icon-favorite{color: $color-sub-theme;}
				}
				&.normal-enter-active, &.normal-leave-active{
					transition: all 0.4s;
					.top, .bottom{transition: all 0.4s cubic-bezier(0.86, 0.18, 0.82, 1.32);}
				}
				&.normal-enter, &.normal-leave-to{
					opacity: 0;
					.top{transform: translate3d(0, -100px, 0);}
					.bottom{transform: translate3d(0, 100px, 0);}
				}
			}	
		}
		.mini-player{
			display: flex;
			align-items: center;
			position: fixed;
			left: 0;
			bottom: 0;
			width: 100%;
			z-index: 180;
			height: 60px;
			background: $color-highlight-background;
			&.mini-enter-active, &.mini-leave-active{transition: all 0.4s;}
      &.mini-enter, &.mini-leave-to{opacity: 0;}
			.icon{
				flex: 0 0 40px;
				width: 40px;
				padding: 0 10px 0 20px;
				img{
					border-radius:50%;
					&.play{animation: rotate 10s linear infinite;}
          &.pause{animation-play-state: paused;}
				}
			}
			.text{
				display: flex;
				flex-direction: column;
				justify-content: center;
				flex: 1;
				line-height: 20px;
				overflow: hidden;
				.name{margin-bottom: 2px;@include no-wrap();font-size: $font-size-medium;color: $color-text;}
				.desc{@include no-wrap();font-size: $font-size-small;color: $color-text-d;}
			}
			.control{flex: 0 0 30px;width: 30px;padding: 0 10px;
				.icon-play-mini, .icon-pause-mini, .icon-playlist{font-size: 30px;color: $color-theme-d;}
				.icon-mini{font-size: 32px;position: absolute;left: 0;top: 0;}
			}
		}
		@keyframes rotate{
			0%{transform: rotate(0)}
			100%{transform: rotate(360deg)}
		}
}
</style>